Livrable 2

Equipe 03

Eugène Dagan, Adrien Bacon, Léo Martin, Adam Meghith, Raphaël Linard et Eric Jouslin de Noray

Introduction

Une célèbre agence d’espionnage a vécu des heures sombres ces dernières semaines. À plusieurs reprises, le matériel mis à disposition sur le terrain pour leurs agents a été détourné. Pour résoudre ce problème, l’agent R propose un prototype de coffre-fort nouvelle génération avec des mécanismes d’authentification plus efficaces.
Pour faciliter la production, un prototype rudimentaire est envisagé à l’aide d’une carte électronique de type Arduino et de composants simples comme des LEDs. L’agent R a rapidement produit un schéma de l’environnement de tests :

Il propose ensuite de doter chaque agent d’une carte électronique avec un numéro (CARD_ID) unique que lui seul connaîtra. En fonction de ce numéro, une série de 4 interrupteurs devra être positionnée avant d’insérer la carte pour activer le système d’authentification. Une fois la carte inséré une combinaison de résistances allumés sera formé et une tension spécifique pour chacun des 8 modèles de carte sera obtenu.
Dans le précédent livrable nous avions fournis l’intégralité des circuits électriques. Dans cette partie nous nous intéresserons tout particulièrement à l’aspect sécurité de notre coffre. Effectivement, nous avons dû créer le système de vérification de l’identité de la personne désireuse d’accéder au coffre.

Montage complet

Lien du Tinkercad :

https://www.tinkercad.com/things/6v5rTeVBWdE-circuit-interne-coffre-ma2?sharecode=IoSc13_SQ-2Wd0OEi9g_L0B4DTxu2NjWp12QwHmB81o

Programme complet de la carte Arduino

Code Arduino MA1 :

int pinAnalogique = A0;                                      //broche analogique pour lire la tention
float tension = 0;                                           //variable pour stocker latension lue
const int ledPins[4] = {4, 5, 6, 7};                         //les différentes broches des LED
const int buttonPins[5] = {8, 9, 10, 11, 12};                //les différentes broches des boutons
int sequence[4] = {0, 1, 2, 3};                              //ordre d'appui initial (sequence)
int currentStep = 0;                                         //étape actuelle de la séquence        
int newSequence[4];                                          //stockage de la nouvelle séquence
bool lastButtonStates[4] = {HIGH, HIGH, HIGH, HIGH};         //états initiaux des bouttons
bool errorOccurred = false;                                  //indicateur d'erreur
bool sequenceComplete = false;                               //indicateur de séquence complète
bool configMode = false;                                     //indicateur du mode Configuration
int configStep = 0;                                          //étape actuelle de la Configuration
int errorCount = 0;                                          //compteur d'erreur
bool lockout = false;                                        //indicateur de bloquage d'essais


void setup(){
  Serial.begin(9600);                                        //initialiser la communication
  for (int i = 0; i < 4; i++){
    pinMode(ledPins[i], OUTPUT);                             //configurer chaque LED en sorties
    digitalWrite(ledPins[i], HIGH);                          //éteindre chaque LED au démarage
    pinMode(buttonPins[i], INPUT_PULLUP);                    //configurer chaque bouton en entrée
  }
}


void loop(){
  int valeurLue = analogRead(pinAnalogique);                 //lire la valeur analogique
  tension = valeurLue * (5.0 / 1023.0);                      //définir cette valeur en une tension
  Serial.print("Tension mesuree: ");
  Serial.print(tension);
  Serial.println(" V");
  delay(1000);
  if (tension >= 1 && tension <= 1.29){                      //verifier si la tension se trouve dans l'intervalle
    Securite1();                                             //lancer le système de sécurité numéro 1
  }
  if (tension >= 1.30 && tension <= 2.05){                   //verifier si la tension se trouve dans l'intervalle
    Securite2();                                             //lancer le système de sécurité numéro 2
  }
  if (tension >= 2.06 && tension <= 2.46){                   //verifier si la tension se trouve dans l'intervalle
    Securite3();                                             //lancer le système de sécurité numéro 3
  }
  if (tension >= 2.47 && tension <= 2.87){                   //verifier si la tension se trouve dans l'intervalle
    Securite4();                                             //lancer le système de sécurité numéro 4
  }
  if (tension >= 2.88 && tension <= 3.05){                   //verifier si la tension se trouve dans l'intervalle
    Securite5();                                             //lancer le système de sécurité numéro 5
  }
  if (tension >= 3.06 && tension <= 3.21){                   //verifier si la tension se trouve dans l'intervalle
    Securite5();                                             //lancer le système de sécurité numéro 5
  }
  if (tension >= 3.22 && tension <= 3.49){                   //verifier si la tension se trouve dans l'intervalle
    Securite2();                                             //lancer le système de sécurité numéro 2
  }
  if (tension >= 3.50 && tension <= 3.71){                   //verifier si la tension se trouve dans l'intervalle
    Securite4();                                             //lancer le système de sécurité numéro 4
  }
}


void MA2(){                                                                          
  if (lockout){
    delay(30000);                                            //attendre 30 secondes
    signalRetry();                                           //signal lumineux pour montrer que l'on peut réessayer
    resetSequence();                                         //Remettre l'étape actuelle de la séaquence à 0
    lockout = false;                                         //Réinitialiser l'indicateur de bloquage d'essais
  }
  if (errorOccurred){
    errorOccurred = false;                                   //Réinitialiser l'indicateur d'erreur
    resetSequence();                                         //Remettre l'étape actuelle de la séaquence à 0
  }
  if (sequenceComplete){
    blinkLEDsInSequence();                                   //signal lumineux de réussite
    enterConfigMode();                                       //entrer dans le mode configuration
    return;
  }
  if (configMode){ 
    configureSequence();                                     //configuration de la séquence
    return;
  }
  for (int i = 0; i < 5; i++){
    bool buttonState = digitalRead(buttonPins[i]);           //lecture d'un changement d'état des boutons poussoirs
    if (buttonState == LOW && lastButtonStates[i] == HIGH){  //si changement d'état de l'un des boutons
      if (i == sequence[currentStep]){                       //si le bouton appuyer est celui correspondant à l'étape de la séquence
        digitalWrite(ledPins[currentStep], LOW);             //allumer la LED corespondant au nombre de l'étape
        currentStep++;                                       //passer à l'étape suivante de la séquence
      } else{
        errorCount++;                                        //Rajouter +1 au compteur d'erreur
        indicateError();                                     
        errorOccurred = true;                                
        if (errorCount >= 4){                                //si le compteur d'erreur est à 4 alors il lance le bloquage d'essais pendant 30 secondes
          lockout = true;
        }
        return;
      }

      delay(50);
      if (currentStep >= 4){                                 //si l'indicateur d'étape est supérieur ou égal à 4 alors dire que la sequence est complété
        sequenceComplete = true;
        return;
      }
    }
    lastButtonStates[i] = buttonState;
  }
}


void indicateError(){                                        //Faire clignoter 3 fois toutes les LED pour montrer une erreur
  for (int j = 0; j < 3; j++){
    for (int k = 0; k < 4; k++){
      digitalWrite(ledPins[k], LOW);
    }
    delay(300);
    for (int k = 0; k < 4; k++){
      digitalWrite(ledPins[k], HIGH);
    }
    delay(300);
  }
}


void resetSequence(){                                        //Eteindre toutes les LED, remettre l'étape de config à 0, remmetre l'étape de la séquence de la config à 0
  for (int j = 0; j < 4; j++){
    digitalWrite(ledPins[j], HIGH);
  }
  currentStep = 0;
  sequenceComplete = false;
  configStep = 0;
}


void blinkLEDsInSequence(){                                 //Faire un signal lumineux 3 fois avec toutes les LED pour signaler une réussite
  for(int repeat = 0; repeat < 3; repeat++){
  for (int i = 0; i < 4; i++) {
    digitalWrite(ledPins[i], LOW);
    delay(200);
    digitalWrite(ledPins[i], HIGH);
    delay(200);
    }
  }
}
  
  
void enterConfigMode(){                                    //Entrer en mode configuration                                  
  configMode = true;
  resetSequence();
}


void configureSequence(){                                  //Configuration de la nouvelle séquence
  for(int i = 0; i < 5; i++){
    bool buttonState = digitalRead(buttonPins[i]);
    if(buttonState == LOW && lastButtonStates[i] == HIGH){
      newSequence[configStep] = i;
      digitalWrite(ledPins[configStep], LOW);
      configStep++;
      delay(300);
      if(configStep >= 4){
        applyNewSequence();
        configMode = false;
      }
    }
    lastButtonStates[i] = buttonState;
  }
}


void applyNewSequence(){                                   //appliquer/remplacer l'ancienne séquence par la nouvelle
  for(int i = 0; i < 4; i++){
    sequence[i] = newSequence[i];
    digitalWrite(ledPins[i], HIGH);
  }
  resetSequence();
}


void signalRetry(){                                        //Faire un signal lumineux avec les LED pour signifier que l'utilisateur peut réessayer                          
  for(int i = 0; i < 6; i++){
    for (int j = 0; j < 4; j++){
      digitalWrite(ledPins[j], LOW);
    }
    delay(250);
    for(int j = 0; j < 4; j++){
      digitalWrite(ledPins[j], HIGH);
    }
    delay(250);
  }
}


void MA1(){
  const int totalQuestions = 3;                                //nombre total de questions
String questions[totalQuestions] = {                         
  "Quand l'agence d'espionnage a t-elle etait cree ?",       //question 1  
  "Comment s'appelle l'agence ?",                            //question 2
  "Qui a cree l'entreprise ?"                                //question 3
};
String reponsesCorrectes[totalQuestions] = {
  "1929",                                                    //réponse 1
  "Secret Service",                                          //réponse 2
  "Adrien et Eric"                                           //réponse 3
};
int questionActuelle = 0;                                    //question actuelle
bool MA1right = false;                                       //Faire une boucle MA1
  Serial.println("Veuillez repondre a ces 3 questions pour prouvez votre identite");                        
  delay(1500);
  Serial.println(questions[questionActuelle]);                                                   //poser la première question
  while(MA1right = true){                                            
    if(Serial.available() > 0){                                                                 //vérification de si il reste des réponses
      String reponseUtilisateur = Serial.readString();                                          //lire la réponse de l'utilisateur
      reponseUtilisateur.trim();                                                                //supprimer les espaces
      if(reponseUtilisateur == reponsesCorrectes[questionActuelle]){                            //si la réponse est correct
        Serial.println("Correct !");                                                              
        delay(1500);                                                                              
        questionActuelle++;                                                                     //passer à la question suivante
      } else{                                                                                   //sinon
        Serial.println("Incorrect. Recommencons depuis le debut.");
        delay(1500);
        questionActuelle = 0;                                                                   //renvoyer à la première question
      }
      if(questionActuelle < totalQuestions){                                                    //verifier s'il reste des questions                                             
        Serial.println(questions[questionActuelle]);                                            //si oui la poser
      } else{
        Serial.println("Premier test d'authentification reussi!");                              //sinon alors réussite du programme
        return;
      }
    }                                                                                      
  }
}


void MA3(){                                                                                   //système de vérification MA3
  Serial.println("Veuillez presenter votre oeil devant la carte arduino");
  delay(15000);
  Serial.println("Votre oeil à été reconnue par la carte");
  delay(5000);
}


void MA4(){                                                                                   //système de vérification MA4
  Serial.println("Veuillez presenter votre doigt devant la carte arduino");
  delay(15000);
  Serial.println("Votre doigt à été reconnue par la carte");
  delay(5000);
}


void MA5(){                                                                                    //système de vérification MA5
  delay(1000);
}


void reussite(){                                                                              //indication de la réussite final
  Serial.println("Vous avez reussi a passer tous les tests d'authentification.");
  delay(1000);
  Serial.println("Ouverture du coffre");
}


void Securite1(){                                                                             //niveau de sécurité 1
  Serial.println("Carte reconnu, code bon");
  MA1();
  MA3();
  reussite();
}


void Securite2(){                                                                             //niveau de sécurité 2
  Serial.println("Carte reconnu, code bon");
  MA1();
  MA4();
  reussite();
}


void Securite3(){                                                                             //niveau de sécurité 3
  Serial.println("Carte reconnu, code bon");
  MA2;
  MA4;
  reussite;
}


void Securite4(){                                                                             //niveau de sécurité 4
  Serial.println("Carte reconnu, code bon");
  MA1();
  MA2();
  MA3();
  MA4();
  reussite;
}


void Securite5(){                                                                             //niveau de sécurité 5
  Serial.println("Carte reconnu, code bon");
  MA1();
  MA2();
  MA3();
  MA4();
  MA5();
  reussite;
}

Sortie :

Tension mesurée : ... V  # Tension mesurée par l'arduino
Carte reconnu, code bon

# Exécution d'un niveau niveau de sécurité qui est défini par le calcule de la tension

Vous avez reussi a passer tous les tests d'authentification.
Ouverture du coffre

Mise en contexte

Les modèles correspondants à leurs tension ainsi que leur niveau de sécurité

Nous précisons que les niveaux de sécurités associés à chaque modèle de carte est choisis de manière purement arbitraire. Dans le tableau ci-dessus les abréviations Ma 1,2,3,4 correspondent au vérification différentes que le coffre est capable de mettre en œuvre.
Par exemple le modèle 1 est associé avec le niveau de sécurité 1 qui comprend les vérification MA1 et MA3.

MA1

Cette vérification est un jeu de question réponse ou l’agent souhaitant accéder au coffre doit donner les bonnes réponses. Si celui-ci se trompe il doit recommencer du début son indentification par le coffre. On peut représenter cette vérification par un programme sous forme de logigramme (voir ci-dessous).

Code Arduino MA1 :

void MA1(){
  const int totalQuestions = 3;                                //nombre total de questions
String questions[totalQuestions] = {                         
  "Quand l'agence d'espionnage a t-elle etait cree ?",       //question 1  
  "Comment s'appelle l'agence ?",                            //question 2
  "Qui a cree l'entreprise ?"                                //question 3
};
String reponsesCorrectes[totalQuestions] = {
  "1929",                                                    //réponse 1
  "Secret Service",                                          //réponse 2
  "Adrien et Eric"                                           //réponse 3
};
int questionActuelle = 0;                                    //question actuelle
bool MA1right = false;                                       //Faire une boucle MA1
  Serial.println("Veuillez repondre a ces 3 questions pour prouvez votre identite");                        
  delay(1500);
  Serial.println(questions[questionActuelle]);                                                   //poser la première question
  while(MA1right = true){                                            
    if(Serial.available() > 0){                                                                 //vérification de si il reste des réponses
      String reponseUtilisateur = Serial.readString();                                          //lire la réponse de l'utilisateur
      reponseUtilisateur.trim();                                                                //supprimer les espaces
      if(reponseUtilisateur == reponsesCorrectes[questionActuelle]){                            //si la réponse est correct
        Serial.println("Correct !");                                                              
        delay(1500);                                                                              
        questionActuelle++;                                                                     //passer à la question suivante
      } else{                                                                                   //sinon
        Serial.println("Incorrect. Recommencons depuis le debut.");
        delay(1500);
        questionActuelle = 0;                                                                   //renvoyer à la première question
      }
      if(questionActuelle < totalQuestions){                                                    //verifier s'il reste des questions                                             
        Serial.println(questions[questionActuelle]);                                            //si oui la poser
      } else{
        Serial.println("Premier test d'authentification reussi!");                              //sinon alors réussite du programme
        return;
      }
    }                                                                                      
  }
}

Sortie :

Quand l'agence d'espionnage a t-elle etait cree ?

1929                           # Réponse de l'utilisateur

Comment s'appelle l'agence ?

Secret Service                 # Réponse de l'utilisateur

Qui a cree l'entreprise ?

Adrien et Eric                 # Réponse de l'utilisateur

Premier test d'authentification reussi!

MA2

Cette seconde vérification est un digicode (code à 4 chiffres) que l’agent doit mettre afin de prouver son éligibilité, puis après la saisie du bon code l’agent doit changer ce code par celui-ci

Code Arduino MA2 :

void MA2(){                                                                          
  if (lockout){
    delay(30000);                                            //attendre 30 secondes
    signalRetry();                                           //signal lumineux pour montrer que l'on peut réessayer
    resetSequence();                                         //Remettre l'étape actuelle de la séaquence à 0
    lockout = false;                                         //Réinitialiser l'indicateur de bloquage d'essais
  }
  if (errorOccurred){
    errorOccurred = false;                                   //Réinitialiser l'indicateur d'erreur
    resetSequence();                                         //Remettre l'étape actuelle de la séaquence à 0
  }
  if (sequenceComplete){
    blinkLEDsInSequence();                                   //signal lumineux de réussite
    enterConfigMode();                                       //entrer dans le mode configuration
    return;
  }
  if (configMode){ 
    configureSequence();                                     //configuration de la séquence
    return;
  }
  for (int i = 0; i < 5; i++){
    bool buttonState = digitalRead(buttonPins[i]);           //lecture d'un changement d'état des boutons poussoirs
    if (buttonState == LOW && lastButtonStates[i] == HIGH){  //si changement d'état de l'un des boutons
      if (i == sequence[currentStep]){                       //si le bouton appuyer est celui correspondant à l'étape de la séquence
        digitalWrite(ledPins[currentStep], LOW);             //allumer la LED corespondant au nombre de l'étape
        currentStep++;                                       //passer à l'étape suivante de la séquence
      } else{
        errorCount++;                                        //Rajouter +1 au compteur d'erreur
        indicateError();                                     
        errorOccurred = true;                                
        if (errorCount >= 4){                                //si le compteur d'erreur est à 4 alors il lance le bloquage d'essais pendant 30 secondes
          lockout = true;
        }
        return;
      }

      delay(50);
      if (currentStep >= 4){                                 //si l'indicateur d'étape est supérieur ou égal à 4 alors dire que la sequence est complété
        sequenceComplete = true;
        return;
      }
    }
    lastButtonStates[i] = buttonState;
  }
}

MA3

Code Arduino MA3 :

Cette troisième vérification vise à faire un scan rétinien à l’aide d’un booléen.

void MA3(){                                                                                   //système de vérification MA3
  Serial.println("Veuillez presenter votre oeil devant la carte arduino");
  delay(15000);
  Serial.println("Votre oeil a été reconnue par la carte");
  delay(5000);
}

Sortie :

Veuillez presenter votre oeil devant la carte arduino

# Scan en cours

Votre oeil a été reconnue par la carte

MA4

Code Arduino MA4 :

Cette quatrième vérification est un deuxième scan cette fois-ci digital à l’aide d’un booléen également.

void MA4(){                                                                                   //système de vérification MA4
  Serial.println("Veuillez presenter votre doigt devant la carte arduino");
  delay(15000);
  Serial.println("Votre doigt a été reconnue par la carte");
  delay(5000);
}

Sortie :

Veuillez presenter votre doigt devant la carte arduino

# Scan en cours

Votre doigt a été reconnue par la carte

MA5

Code Arduino MA5 :

Cette ultime vérification a pour objectif de confirmer l’identité d’une personne souhaitant accéder au coffre-fort Elle doit d saisir l’identifiant de sa carte pour prouver son éligibilité.


# Non terminé

void MA5(){                                                                                    //système de vérification MA5
  delay(1000);
}

Conclusion

En conclusion, nous n’avons pas réussi à faire fonctionner le montage complet du coffre mais les différents code des niveaux de sécurité fonctionnent, sauf pour le niveau 5 que nous n’avons pas terminé à temps. Puis nous ne sommes pas arrivé à calculer la tension voulue.